package com.qwt.part_time_api.common.provider;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.qwt.part_time_api.service.impl.UserDetailServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpSession;

/**
 * @author Tzeao
 * 自定义登陆密码验证
 */
@Component
@Slf4j
public class CustomAuthenticationProvider implements AuthenticationProvider {

    private final PasswordEncoder encoder = new BCryptPasswordEncoder();
    @Autowired
    private UserDetailServiceImpl userService;

    /**
     * 自定义验证方式
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        log.info("登录密码校验");
        String username = authentication.getName();
        String password = (String) authentication.getCredentials();

        if (username == null || "".equals(username)) {
            log.info("账号不能为空");
            throw new BadCredentialsException("账号不能为空");
        }

        //获取数据库的信息
        UserDetails node = userService.loadUserByUsername(username);

        if (StringUtils.isEmpty(password)) {
            password = "QWT_PASSWORD";
        }

        // 获取Request, 获取其他参数信息
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpSession session = attributes.getRequest().getSession();
        Object others = session.getAttribute("others");

        //密码校验
        if (!encoder.matches(password, node.getPassword())) {
            log.info("用户名或密码不正确");
            throw new BadCredentialsException("用户不存在或账号错误");
        }
        return new UsernamePasswordAuthenticationToken(node, password, node.getAuthorities());
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }
}